﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace EntregaSO
{
    class Simulador
    {
        int maxPisos = 15;
        int maxAsc = 5;
        int cantSolicitudes = 60;
        int maxPeso = 200;
        bool random;

        public Simulador(int maxPisos, int maxAsc, int maxPeso, int cantSolicitudes, bool random)
        {
            this.cantSolicitudes = cantSolicitudes;
            this.maxPeso = maxPeso;
            this.maxPisos = maxPisos;
            this.maxAsc = maxAsc;
            this.random = random;
        }
        public void Start()
        {
            int cantidadPisos;
            int cantidadAsc;
            Random r = new Random();
                
            if (random)
            {
                cantidadPisos = Convert.ToInt32(r.Next(1, maxPisos));
                cantidadAsc = Convert.ToInt32(r.Next(1, maxAsc));
            }
            else
            {
                cantidadAsc = this.maxAsc;
                cantidadPisos = this.maxPisos;
            }
            Planificador p = new PlanificadorDistribuido(cantidadPisos,cantidadAsc);
            int i = 0;
            int peso, pisoOrigen, pisoDestino;

            //escribo el titulo en el archivo con los datos de entrada de la simulacion
            EscribirADisco escritorDatosSim = new EscribirADisco("DatosSimulacion.txt");
            escritorDatosSim.Escribir.WriteLine("Datos de entrada de la simulación");
            escritorDatosSim.Escribir.WriteLine("*********************************");
            escritorDatosSim.Escribir.WriteLine();
            escritorDatosSim.Escribir.Flush();

            //escribo el titulo en el archivo con los datos de salida de la simulación
            p.Escritor.Escribir.WriteLine("ESTADISTICAS DE LA SIMULACIÓN");
            p.Escritor.Escribir.WriteLine("-----------------------------");
            p.Escritor.Escribir.WriteLine("Estadisticas de los usuarios");
            p.Escritor.Escribir.WriteLine("****************************");
            p.Escritor.Escribir.WriteLine();
            p.Escritor.Escribir.Flush();

            
            while (i < cantSolicitudes)
            {
                peso = Convert.ToInt32(r.Next(30,maxPeso));
                pisoOrigen = Convert.ToInt32(r.Next(0, cantidadPisos));
                pisoDestino = Convert.ToInt32(r.Next(0, cantidadPisos));
                p.CrearUsuario(pisoOrigen, pisoDestino, peso);

                //escribo los datos de la simulación
                escritorDatosSim.Escribir.WriteLine("Solicitud " + i + ": ");
                escritorDatosSim.Escribir.WriteLine("Piso origen: " + pisoOrigen + "; Piso destino: " +
                    pisoDestino + "; Peso persona: " + peso + ".");
                escritorDatosSim.Escribir.Flush();
                
                Thread solicitud = new Thread(p.CrearSolicitud);
                solicitud.Start(pisoOrigen);
                solicitud.Join();

                Thread planificar = new Thread(p.Planificar);
                planificar.Start();
                planificar.Join();

                i++;
            }
            Thread avanzar;
            List<Thread> hilos = new List<Thread>();
            while (true)
            {
                hilos.Clear();
                foreach (Ascensor a in p.Ascensores)
                {
                    avanzar = new Thread(a.Avanzar);
                    hilos.Add(avanzar);
                }
                foreach (Thread t in hilos)
                {
                    t.Start();
                    t.Join();
                }
            }

            //cierro el archivo con los datos de la simulacion
            escritorDatosSim.Escribir.Close();
            
            //imprimo estadisticas de los ascensores
            p.Escritor.Escribir.WriteLine();
            p.Escritor.Escribir.WriteLine("Estadisticas de los ascensores");
            p.Escritor.Escribir.WriteLine("******************************");
            p.Escritor.Escribir.Flush();

            foreach (Ascensor a in p.Ascensores)
            {
                p.Escritor.Escribir.WriteLine(a.estadisticasTiempoDeUso.ImprimirResultados());
                p.Escritor.Escribir.WriteLine(a.estadisticasCarga.ImprimirResultados());
                p.Escritor.Escribir.WriteLine(a.estadisticasDistancia.ImprimirResultados());
                p.Escritor.Escribir.WriteLine(a.estadisticasPasajeros.ImprimirResultados());
                p.Escritor.Escribir.Flush();
            }

            p.Escritor.Escribir.Close();
         }
    }
}
